package com.jarvan.service.impl;

import com.alibaba.fastjson.JSON;
import com.jarvan.dto.TrainDto;
import com.jarvan.enums.ResultEnum;
import com.jarvan.enums.TrainEnum;
import com.jarvan.exception.TrainException;
import com.jarvan.form.TrainForm;
import com.jarvan.model.Ticket;
import com.jarvan.model.Trains;
import com.jarvan.repository.TrainsRepository;
import com.jarvan.service.TrainsService;
import com.jarvan.utils.PrefixUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class TrainsServiceImpl implements TrainsService {

    @Autowired
    private TrainsRepository repository;

    @Autowired
    private TicketServiceImpl ticketService;

    @Override
    public Trains save(TrainForm trainForm) {
        Trains trains = new Trains();
        BeanUtils.copyProperties(trainForm, trains);
        int hours = (int) Math.floor((double)trainForm.getTotalMin() / 60);
        int minutes = trainForm.getTotalMin() % 60;
        int startHour = Integer.parseInt(trainForm.getStartTime().substring(0, 2));
        int startMinute = Integer.parseInt(trainForm.getStartTime().substring(3,5));
        int day = 0;
        int endMinute;
        int endHour = 0;
        int divideHour;
        if ((startMinute + minutes) > 60){
            hours += 1;
            endMinute = minutes + startMinute -60;
        } else {
            endMinute = minutes + startMinute;
        }

        if (hours > 24){
            day = (int)Math.floor((double) hours / 24);
            divideHour = hours % 24;
            if ((startHour + divideHour) > 24){
                day += 1;
                endHour = startHour + divideHour -24;
            }
        }else {
            endHour = startHour + hours;
        }

        trains.setEndTime(PrefixUtil.prefix(endHour)+":"+PrefixUtil.prefix(endMinute));
        trains.setTotalDay(day);

        //TODO 所有经过的车站
        String str = trainForm.getStationInfos().replaceAll("\\\\","");
        trains.setStations(str);
        return repository.save(trains);
    }

    @Override
    public Page<Trains> findAll(Pageable pageable) {
        return repository.findAll(pageable);
    }

    @Override
    public Trains findOne(String trainId) {
        Trains result =  repository.findById(trainId).orElse(null);
        if (result == null){
            log.error("[火车查询] 火车不存在  trainId={}", trainId);
            throw new TrainException(ResultEnum.TRAIN_NOT_EXIST.getCode(), ResultEnum.TRAIN_NOT_EXIST.getMessage());
        }
        return result;
    }


    @Override
    public void remove(String trainId) {
        Trains trains = repository.findById(trainId).orElse(null);
        if (trains ==null){
            log.error("[火车查询]  通过id查询  trainId={}", trainId);
            throw new TrainException(ResultEnum.TRAIN_NOT_EXIST.getCode(), ResultEnum.TRAIN_NOT_EXIST.getMessage());
        }
        trains.setTrainStatus(TrainEnum.DEPRECED.getCode());
        repository.save(trains);
    }

    @Override
    public Page<Trains> findByStatus(Integer status, Pageable pageable) {
        return repository.findAllByTrainStatus(status, pageable);
    }

    @Override
    public void recover(String trainId) {
        Trains trains = repository.findById(trainId).orElse(null);
        if (trains ==null){
            log.error("[火车查询]  通过id查询  trainId={}", trainId);
            throw new TrainException(ResultEnum.TRAIN_NOT_EXIST.getCode(), ResultEnum.TRAIN_NOT_EXIST.getMessage());
        }
        trains.setTrainStatus(TrainEnum.NORMAL.getCode());
        repository.save(trains);
    }

    @Override
    public List<Trains> findByStartAndEnd(String start, String end) {
        return repository.findByStartAndEnd(start, end);
    }

    @Override
    public List<TrainDto> findByDepartureAndDistination(String start, String end, String date) {
        List<Trains> trains =  repository.findAllByStationsContainingAndStationsContaining(start, end);
        List<TrainDto> dtos= new ArrayList<>();
        TrainDto dto = new TrainDto();
        trains.forEach(e -> {
            List<Ticket> tickets = ticketService.findAllByTrainAndDate(e.getTrainId(), date);
            int ticketCount = e.getSeatCount() * e.getCarriage() - tickets.size();
            List<String> stationInfos = JSON.parseArray(e.getStations(), String.class);
            int targetIndex = stationInfos.indexOf(start);
            for (Ticket ticket: tickets){
                int ticketIndex = stationInfos.indexOf(ticket.getDestination());
                if (ticketIndex < targetIndex){
                    ticketCount += 1;
               }
            }
            BeanUtils.copyProperties(e, dto);
            dto.setTicketCount(ticketCount);
            dto.setStationInfos(stationInfos);
            dtos.add(dto);
        });
        return dtos;
    }
}
